/* ----------------------------------------------------------------
 * Programmer(s): Daniel R. Reynolds @ SMU
 *                Scott Cohen, Alan Hindmarsh, Radu Serban, and
 *                Aaron Collier @ LLNL
 * ----------------------------------------------------------------
 * SUNDIALS Copyright Start
 * Copyright (c) 2002-2025, Lawrence Livermore National Security
 * and Southern Methodist University.
 * All rights reserved.
 *
 * See the top-level LICENSE and NOTICE files for details.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 * SUNDIALS Copyright End
 * ----------------------------------------------------------------
 * This is the header file for KINSOL's linear solver interface.
 * ----------------------------------------------------------------*/

#ifndef _KINLS_H
#define _KINLS_H

#include <sundials/sundials_direct.h>
#include <sundials/sundials_iterative.h>
#include <sundials/sundials_linearsolver.h>
#include <sundials/sundials_matrix.h>
#include <sundials/sundials_nvector.h>

#ifdef __cplusplus /* wrapper to enable C++ usage */
extern "C" {
#endif

/*==================================================================
  KINLS Constants
  ==================================================================*/

#define KINLS_SUCCESS 0

#define KINLS_MEM_NULL    -1
#define KINLS_LMEM_NULL   -2
#define KINLS_ILL_INPUT   -3
#define KINLS_MEM_FAIL    -4
#define KINLS_PMEM_NULL   -5
#define KINLS_JACFUNC_ERR -6
#define KINLS_SUNMAT_FAIL -7
#define KINLS_SUNLS_FAIL  -8

/*===============================================================
  KINLS user-supplied function prototypes
  ===============================================================*/

typedef int (*KINLsJacFn)(N_Vector u, N_Vector fu, SUNMatrix J, void* user_data,
                          N_Vector tmp1, N_Vector tmp2);

typedef int (*KINLsPrecSetupFn)(N_Vector uu, N_Vector uscale, N_Vector fval,
                                N_Vector fscale, void* user_data);

typedef int (*KINLsPrecSolveFn)(N_Vector uu, N_Vector uscale, N_Vector fval,
                                N_Vector fscale, N_Vector vv, void* user_data);

typedef int (*KINLsJacTimesVecFn)(N_Vector v, N_Vector Jv, N_Vector uu,
                                  sunbooleantype* new_uu, void* J_data);

/*==================================================================
  KINLS Exported functions
  ==================================================================*/

SUNDIALS_EXPORT int KINSetLinearSolver(void* kinmem, SUNLinearSolver LS,
                                       SUNMatrix A);

/*-----------------------------------------------------------------
  Optional inputs to the KINLS linear solver interface
  -----------------------------------------------------------------*/

SUNDIALS_EXPORT int KINSetJacFn(void* kinmem, KINLsJacFn jac);
SUNDIALS_EXPORT int KINSetPreconditioner(void* kinmem, KINLsPrecSetupFn psetup,
                                         KINLsPrecSolveFn psolve);
SUNDIALS_EXPORT int KINSetJacTimesVecFn(void* kinmem, KINLsJacTimesVecFn jtv);

/*-----------------------------------------------------------------
  Optional outputs from the KINLS linear solver interface
  -----------------------------------------------------------------*/

SUNDIALS_EXPORT int KINGetJac(void* kinmem, SUNMatrix* J);
SUNDIALS_EXPORT int KINGetJacNumIters(void* kinmem, long int* nni_J);
SUNDIALS_DEPRECATED_EXPORT_MSG(
  "Work space functions will be removed in version 8.0.0")
int KINGetLinWorkSpace(void* kinmem, long int* lenrwLS, long int* leniwLS);
SUNDIALS_EXPORT int KINGetNumJacEvals(void* kinmem, long int* njevals);
SUNDIALS_EXPORT int KINGetNumLinFuncEvals(void* kinmem, long int* nfevals);
SUNDIALS_EXPORT int KINGetNumPrecEvals(void* kinmem, long int* npevals);
SUNDIALS_EXPORT int KINGetNumPrecSolves(void* kinmem, long int* npsolves);
SUNDIALS_EXPORT int KINGetNumLinIters(void* kinmem, long int* nliters);
SUNDIALS_EXPORT int KINGetNumLinConvFails(void* kinmem, long int* nlcfails);
SUNDIALS_EXPORT int KINGetNumJtimesEvals(void* kinmem, long int* njvevals);
SUNDIALS_EXPORT int KINGetLastLinFlag(void* kinmem, long int* flag);
SUNDIALS_EXPORT char* KINGetLinReturnFlagName(long int flag);

#ifdef __cplusplus
}
#endif

#endif
